﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GestionePolveri2.DAL;
using GestionePolveriLib.BL;
using FrameworkLib.Facades;

namespace GestionePolveriLib.Facades
{
    [Serializable]
    public class ComposizioneColoreFacadeExt : ComposizioneColoreFacade //FacadeBase<GestionePolveriEntities>
    {
        GestionePolveriEntities context = null;

        public ComposizioneColoreFacadeExt()
        {
            context = this.GetContext();
        }

        public ComposizioneColoreFacadeExt(string connectionString)
        {
            context = this.GetContext(connectionString);
        }

        public new void LoadAsync(BackgroundWorkerCallbackBase.Callback callback)
        {
            this.RunAsync(() => GetAll(), callback);
        }

        public new List<ComposizioneColoreExt> GetAll()
        {
            List<ComposizioneColoreExt> retValue = null;

            try
            {
                var obj = from x in context.ComposizioneColori
                          select new ComposizioneColoreExt
                          {
                              ID = x.IDComposizione,
                              Colore = (from y in context.AnagColori
                                        where y.IDColore == x.IDColore
                                        select new Colore
                                        {
                                            ID = y.IDColore,
                                            CodiceColore = y.CodiceColore,
                                            Descrizione = y.Descrizione,
                                            Famiglia = (from f in context.AnagFamiglie
                                                        where f.IDFamiglia == y.IDFamiglia
                                                        select new FamigliaColore
                                                        {
                                                            ID = f.IDFamiglia,
                                                            Descrizione = f.Descrizione
                                                        }).FirstOrDefault()
                                        }).FirstOrDefault(),
                              //Polveri = (from z in context.AnagPolveri
                              //           where z.IDPolvere == x.IDPolvere
                              //           select new PolvereExt
                              //           {
                              //               Descrizione = z.Descrizione
                              //           }),
                              Applicazione = x.Applicazione
                          };

                if (obj.Any())
                {
                    retValue = obj.ToList();
                }
            }
            catch (Exception ex)
            {
                // throw ex;
            }

            return retValue;
        }

        public bool Add(ComposizioneColoreExt data)
        {
            bool retValue = false;

            try
            {
                Transact(() => {
                    foreach (PolvereExt p in data.Polveri)
                    {
                        ComposizioneColori imp = new ComposizioneColori();
                        imp.IDColore = data.Colore.ID;
                        imp.IDPolvere = p.ID;
                        imp.Applicazione = string.Format("{0}{1}", (p.Base ? "b" : ""), (p.Venatura ? "v" : ""));
                        
                        context.ComposizioneColori.AddObject(imp);
                        context.SaveChanges();

                        retValue = true;
                    }
                });
            }
            catch (Exception ex)
            {
                // throw ex;
            }

            return retValue;
        }

        public bool Add(List<ComposizioneColoreExt> data)
        {
            bool retValue = false;

            Transact(() =>
            {
                foreach (ComposizioneColoreExt cc in data)
                {
                    Add(cc);
                }

                context.SaveChanges();
                retValue = true;
            });

            return retValue;
        }

        public bool Delete(ComposizioneColoreExt data)
        {
            bool retValue = false;

            try
            {
                var obj = from x in context.ComposizioneColori
                          where x.IDComposizione == data.ID
                          select x;

                if (obj.Any())
                {
                    context.ComposizioneColori.DeleteObject(obj.FirstOrDefault());

                    context.SaveChanges();
                    retValue = true;
                }
            }
            catch (Exception ex)
            {
                // throw ex;
            }

            return retValue;
        }

        public bool DeleteByColore(ComposizioneColoreExt data)
        {
            bool retValue = false;

            try
            {
                var obj = from x in context.ComposizioneColori
                          where x.IDColore == data.Colore.ID
                          select x;

                if (obj.Any())
                {
                    Transact(() =>
                    {
                        foreach (ComposizioneColori cc in obj.ToList())
                        {
                            context.ComposizioneColori.DeleteObject(cc);
                        }

                        context.SaveChanges();
                        retValue = true;
                    });
                }
            }
            catch (Exception ex)
            {
                // throw ex;
            }

            return retValue;
        }

        public bool DeleteByPolvere(ComposizioneColoreExt data)
        {
            bool retValue = false;

            try
            {
                var obj = from x in context.ComposizioneColori
                          where x.IDColore == data.Colore.ID
                          select x;

                if (obj.Any())
                {
                    foreach (ComposizioneColori cc in obj.ToList())
                    {
                        context.ComposizioneColori.DeleteObject(cc);
                    }

                    context.SaveChanges();
                    retValue = true;
                }
            }
            catch (Exception ex)
            {
                // throw ex;
            }

            return retValue;
        }

        public bool Modify(ComposizioneColoreExt data)
        {
            bool retValue = false;

            try
            {
                var obj = from x in context.ComposizioneColori
                          where x.IDColore == data.Colore.ID
                          select new ComposizioneColore() {
                              ID = x.IDComposizione
                          };

                if (obj.Any())
                {
                    Transact(() =>
                    {
                        List<ComposizioneColore> m_composizioni = (List<ComposizioneColore>)obj.ToList();

                        // cancello la formula precedente...
                        foreach (ComposizioneColore cc in m_composizioni)
                        {
                            var objToDelete = from x in context.ComposizioneColori
                                              where x.IDComposizione == cc.ID
                                              select x;

                            if (obj.Any())
                            {
                                context.ComposizioneColori.DeleteObject(objToDelete.FirstOrDefault());
                            }
                        }

                        // inserisco la nuova formula...
                        foreach (PolvereExt p in data.Polveri)
                        {
                            ComposizioneColori imp = new ComposizioneColori();
                            imp.IDColore = data.Colore.ID;
                            imp.IDPolvere = p.ID;
                            imp.Applicazione = string.Format("{0}{1}", (p.Base ? "b" : ""), (p.Venatura ? "v" : ""));

                            context.ComposizioneColori.AddObject(imp);
                        }

                        context.SaveChanges();
                        retValue = true;
                    });
                }
            }
            catch (Exception ex)
            {
                // throw ex;
            }

            return retValue;
        }

        public ComposizioneColoreExt Get(int id)
        {
            ComposizioneColoreExt retValue = null;

            var obj = from x in context.ComposizioneColori
                      where x.IDComposizione == id
                      select new ComposizioneColoreExt
                      {
                          ID = x.IDComposizione,
                          Colore = (from c in context.AnagColori
                                    where c.IDColore == x.IDColore
                                    select new Colore
                                    {
                                        ID = c.IDColore,
                                        CodiceColore = c.CodiceColore
                                    }).FirstOrDefault(),
                          Applicazione = x.Applicazione
                      };

            if (obj.Any())
            {
                retValue = obj.FirstOrDefault();
            }

            return retValue;
        }

        public List<ComposizioneColoreExt> GetByColore(int idColore)
        {
            List<ComposizioneColoreExt> retValue = null;

            var obj = from x in context.ComposizioneColori
                      where x.IDColore == idColore
                      select new ComposizioneColoreExt
                      {
                          ID = x.IDComposizione
                      };

            if (obj.Any())
            {
                retValue = obj.ToList();
            }

            return retValue;
        }

        public List<ComposizioneColoreExt> GetByPolvere(int idPolvere)
        {
            List<ComposizioneColoreExt> retValue = null;

            var obj = from x in context.ComposizioneColori
                      where x.IDPolvere == idPolvere
                      select new ComposizioneColoreExt
                      {
                          ID = x.IDComposizione
                      };

            if (obj.Any())
            {
                retValue = obj.ToList();
            }

            return retValue;
        }

        public List<Colore> GetColoriAssociati(int polvereId)
        {
            List<Colore> retValue = null;

            try
            {
                this.Transact(() => { });

                var obj = (from x in context.ComposizioneColori
                          where x.IDPolvere == polvereId
                          select new Colore
                          {
                              ID = x.AnagColori.IDColore,
                              CodiceColore = x.AnagColori.CodiceColore,
                              Applicazione = x.AnagColori.ComposizioneColori.FirstOrDefault().Applicazione,
                              Famiglia = (from y in context.AnagFamiglie
                                          where y.IDFamiglia == x.AnagColori.IDFamiglia
                                          select new FamigliaColore
                                          {
                                              ID = y.IDFamiglia,
                                              Descrizione = y.Descrizione
                                          }).FirstOrDefault()
                          });

                if (obj.Any())
                {
                    retValue = obj.ToList();
                }

            }
            catch (Exception ex)
            {
                // throw ex;
            }

            return retValue;
        }

        public string GetColoriAssociati2(int polvereId)
        {
            string retValue = null;

            try
            {
                var obj = from x in context.ComposizioneColori
                          where x.IDPolvere == polvereId
                          select new Colore
                          {
                              CodiceColore = x.AnagColori.CodiceColore,
                              Applicazione = x.Applicazione
                          };

                if (obj.Any())
                {
                    foreach (Colore c in obj.ToList())
                    {
                        retValue += string.Format("{0}/{1} ", c.CodiceColore, c.Applicazione);
                    }
                }

            }
            catch (Exception ex)
            {
                // throw ex;
            }

            return retValue;
        }

        public List<PolvereExt> GetPolveriAssociate(int coloreId)
        {
            List<PolvereExt> retValue = null;

            try
            {
                var obj = from x in context.ComposizioneColori
                          where x.IDColore == coloreId
                          select new PolvereExt
                          {
                              ID = x.AnagPolveri.IDPolvere,
                              CodicePolvere = x.AnagPolveri.CodicePolvere,
                              Base = (x.Applicazione == "b" ? true : (x.Applicazione == "bv" ? true : false)),
                              Venatura = (x.Applicazione == "v" ? true : (x.Applicazione == "bv" ? true : false)),
                              Descrizione = x.AnagPolveri.Descrizione,
                              Note = x.AnagPolveri.Note,
                              FamiglieColori = (from y in context.ComposizioneColori
                                                where y.IDPolvere == x.AnagPolveri.IDPolvere
                                                select y.AnagColori.AnagFamiglie.Descrizione
                                                ).FirstOrDefault(),
                              Fornitore = (from f in context.AnagFornitori
                                           where f.IDFornitore == x.AnagPolveri.IDFornitore
                                           select new Fornitore { ID=f.IDFornitore, Descrizione=f.Descrizione }).FirstOrDefault()
                          };

                if (obj.Any())
                {
                    retValue = obj.ToList();
                }
            }
            catch (Exception ex)
            {
                // throw ex;
            }

            return retValue;
        }

        public string GetApplicazioneColore(int idColore)
        {
            string retValue = null;

            try
            {
                var obj = from x in context.ComposizioneColori
                          where x.IDColore == idColore
                          select x.Applicazione;

                if (obj.Any())
                {
                    foreach (string a in obj)
                    {
                        retValue += a + ",";
                    }

                    retValue = retValue.Substring(0, retValue.LastIndexOf(","));
                }
            }
            catch (Exception ex)
            {
                // throw ex;
            }

            return retValue;
        }

        public string GetFamiglieColoriAssociate(int polvereId)
        {
            string retValue = null;

            try
            {
                var obj = from x in context.ComposizioneColori
                          where x.IDPolvere == polvereId
                          select x.AnagColori.AnagFamiglie.Descrizione;

                if (obj.Any())
                {
                    retValue = obj.FirstOrDefault();
                }
            }
            catch (Exception ex)
            {
                // throw ex;
            }

            return retValue;
        }
    }
}
